package com.fjwt.gz.service.wx;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.bo.CouponResultBo;
import com.fjwt.gz.db.entity.AwardCouponEntity;
import com.fjwt.gz.db.entity.AwardSettingEntity;
import com.fjwt.gz.db.entity.FansEntity;
import com.fjwt.gz.service.impl.AwardCouponService;
import com.fjwt.gz.service.impl.AwardSettingService;
import com.fjwt.gz.service.impl.FansService;
import com.fjwt.gz.util.PeriodUtil;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.cashcoupons.CashCouponsService;
import com.wechat.pay.java.service.cashcoupons.model.Coupon;
import com.wechat.pay.java.service.cashcoupons.model.QueryCouponRequest;
import com.wechat.pay.java.service.cashcoupons.model.SendCouponRequest;
import com.wechat.pay.java.service.cashcoupons.model.SendCouponResponse;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 微信发券
 */
@Slf4j
@Service
public class WxCouponsServiceImpl implements IWxCouponsService {

    @Autowired
    private IWxConfigService wxConfigService;

    @Autowired
    private FansService fansService;

    @Autowired
    private AwardCouponService couponAwardService;

    @Autowired
    private AwardSettingService awardSettingService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CouponResultBo sendCoupons(@NonNull AwardCouponEntity awardCouponEntity, Long fansId) {
        log.info("微信发券，fansId:{},awardCouponEntity:{}",fansId,JSONUtil.toJsonStr(awardCouponEntity));
        Long couponId = awardCouponEntity.getCouponId();
        FansEntity fansEntity = fansService.getById(fansId);
        String openid = fansEntity.getPayOpenId();

        String payConfig = awardCouponEntity.getPayConfig();
        if(StrUtil.isEmpty(payConfig)){
            throw new BizException("卡券奖品参数未配置！");
        }
        long sTime = awardCouponEntity.getStartTime().getTime() / 1000;
        long eTime = awardCouponEntity.getEndTime().getTime()/ 1000;
        long time = System.currentTimeMillis() / 1000;

        if(time < sTime){
            throw new BizException("卡券活动未开始！");
        }

        if(time > eTime){
            throw new BizException("卡券活动已结束！");
        }
        String outRequestNo = openid + "_" + DateUtil.format(new Date(), "yyyyMMddHHmmss");
        CashCouponsService service = new CashCouponsService.Builder().config(wxConfigService.getConfig()).build();
        SendCouponRequest request = new SendCouponRequest();
        request.setStockId(payConfig);
        request.setAppid("wx2df374fb893f510d");
        request.setOpenid(openid);
        request.setOutRequestNo(outRequestNo);
        request.setStockCreatorMchid("1628242998");
        log.info("用户openid：{}，卡券couponId：{}，领券请求参数：{}",openid,couponId, JSON.toJSONString(request));
        try{
            SendCouponResponse  re =  service.sendCoupon(request);
            log.info("用户openid：{}，卡券couponId：{}，领券返回参数：{}",openid,couponId,JSON.toJSONString(re));
            String couponIdwx = re.getCouponId();

            CouponResultBo couponResultBo=new CouponResultBo();
            couponResultBo.setCouponThirdId(couponIdwx);
            return  couponResultBo;

        }catch(ServiceException e){
            e.printStackTrace();

            log.info("用户openid：{}，卡券couponId：{}，领券返回异常参数：{}",openid,couponId,JSON.toJSONString(e));
            throw new BizException("微信发放卡券失败： "+e.getErrorMessage());
         }

    }


    /**
     * 检查周期性发放限制,true超过数量限制，false没有超过
     */
    public void checkPeriodNum(AwardCouponEntity awardCouponEntity) {
        String type = "";
        boolean isOverNum = false;//是否超发
        //根据卡券id查询 setting 表
        AwardSettingEntity awardSetting = awardSettingService.getOne(AwardSettingEntity.gw()
                .eq(AwardSettingEntity::getAwardId, awardCouponEntity.getCouponId()));
//                判断周期性次数
        final Integer periodType = awardSetting.getPeriodType();//限制周期类型
        if (periodType != null && periodType > 0) {
            int currentPeriodNum = awardSetting.getCurrentPeriodTimes();//当前周期次数
            int historyPeriod = awardSetting.getCurrentPeriodType();//当前类型  第几天 第几周
            final int periodTimes = awardSetting.getPeriodTimes();//限制周期次数
            int currentPeriod = PeriodUtil.getPeriod(periodType);
            if (currentPeriod == historyPeriod) {
                if (currentPeriodNum >= periodTimes) {
                     type = periodType == 1 ? "日" : periodType == 2 ? "周" : "月";
                    log.info(String.format("该卡券奖品\"%s\"每%s领取数量已达上限", awardCouponEntity.getCouponName(), type));
                    isOverNum = true;
                } else {
                    currentPeriodNum++;
                    awardSetting.setCurrentPeriodTimes(currentPeriodNum);
                    isOverNum = false;
                }
            } else {
                awardSetting.setCurrentPeriodTimes(1);
                awardSetting.setCurrentPeriodType(currentPeriod);
                isOverNum = false;
            }
        }else {
            return;
        }
        if (isOverNum) {
            throw new BizException(String.format("\"%s\"每%s领取数量已达上限", awardCouponEntity.getCouponName(), type));
        } else {
            boolean isUpdate = awardSettingService.updateById(awardSetting);
            if (!isUpdate) {
                log.info("发放卡券，周期性限制并发问题");
                throw new BizException("活动太火爆了，请稍后再试!");
            }
        }
    }

    @Override
    public String queryCoupon(String openid,String appid,String couponid) throws Exception {

        CashCouponsService service = new CashCouponsService.Builder().config(wxConfigService.getConfig()).build();

        QueryCouponRequest request = new QueryCouponRequest();

        request.setAppid(appid);
        request.setOpenid(openid);
        request.setCouponId(couponid);
        Coupon coupon =service.queryCoupon(request);

        if(coupon == null){
            return "0";
        }

        return JSONUtil.toJsonStr(coupon);
    }
}
